package io.github.hadyang.leetcode.offer;

import org.junit.Test;

/** @author haoyang.shi */
public class IsNumeric {

  @Test
  public void test() {

    System.out.println(isNumeric("+100".toCharArray()));
    System.out.println(isNumeric("5e2".toCharArray()));
    System.out.println(isNumeric("-123".toCharArray()));
    System.out.println(isNumeric("3.1416".toCharArray()));
    System.out.println(isNumeric("-1E-16".toCharArray()));

    System.out.println(isNumeric("12e".toCharArray()));
    System.out.println(isNumeric("1a3.14".toCharArray()));
    System.out.println(isNumeric("1.2.3".toCharArray()));
    System.out.println(isNumeric("+-5".toCharArray()));
    System.out.println(isNumeric("12e+4.3".toCharArray()));
  }

  public boolean isNumeric(char[] str) {
    if (str == null || str.length == 0) return false;

    int index = scanInteger(str, 0);

    boolean numeric = index != 0;

    // 小数
    if (index < str.length && str[index] == '.') {
      index++;
      int pre = index;
      index = scanUnsignedInteger(str, index);

      // 1. 小数可以没有整数部分
      // 2. 小数后可以没有数字
      // 3. 小数后可以有数字
      numeric |= index != pre;
    }

    // 指数
    if (index < str.length && (str[index] == 'e' || str[index] == 'E')) {
      index++;
      int pre = index;
      index = scanInteger(str, index);

      // 1. e或者E之前必须有数字
      // 2. e或者E之后必须有数字
      numeric &= index != pre;
    }

    return numeric && index == str.length;
  }

  private int scanInteger(char[] str, int s) {
    if (s < str.length && (str[s] == '+' || str[s] == '-')) s++;

    return scanUnsignedInteger(str, s);
  }

  private int scanUnsignedInteger(char[] str, int s) {
    while (s < str.length && str[s] >= '0' && str[s] <= '9') {
      s++;
    }

    return s;
  }
}
